﻿using System;
using System.Diagnostics.Tracing;
using System.Threading;

namespace Sustainalytics.EsgRatings.BusinessLogic
{
    //todo Petre  move content to another source
    [EventSource(Name = "Sustainalytics-WeightMatrices")]
    public sealed class WeightMatricesEventSource : EventSource
    {
        private static Lazy<WeightMatricesEventSource> _lazyLog = new Lazy<WeightMatricesEventSource>(InitLog, LazyThreadSafetyMode.ExecutionAndPublication);

        public static WeightMatricesEventSource Log => _lazyLog.Value;

        [NonEvent]
        private static WeightMatricesEventSource InitLog()
        {
            var log = new WeightMatricesEventSource();
            log.Ping();

            return log;
        }

        [Event(1, Level = EventLevel.LogAlways)]
        public void Ping()
        {
            if (IsEnabled())
            {
                WriteEvent(1);
            }
        }

        [Event(101, Task = Tasks.LoadWeightMatrixForProcessing, Opcode = EventOpcode.Start, Level = EventLevel.Informational, Message = "LoadWeightMatrixForProcessing/Start")]
        public void LoadWeightMatrixForProcessingStart(string matrixFileName, int matrixFileContentBytes, string matrixFileContentType)
        {
            if (IsEnabled())
            {
                WriteEvent(101, matrixFileName, matrixFileContentBytes, matrixFileContentType);
            }
        }

        [Event(102, Task = Tasks.LoadWeightMatrixForProcessing, Opcode = EventOpcode.Stop, Level = EventLevel.Informational, Message = "LoadWeightMatrixForProcessing/Stop")]
        public void LoadWeightMatrixForProcessingStop(string matrixFileName, int matrixFileContentBytes, string matrixFileContentType)
        {
            if (IsEnabled())
            {
                WriteEvent(102, matrixFileName, matrixFileContentBytes, matrixFileContentType);
            }
        }

        [Event(103, Level = EventLevel.Error, Message = "LoadWeightMatrixForProcessing/Failed")]
        public void LoadWeightMatrixForProcessingFailed(string matrixFileName, int matrixFileContentBytes, string matrixFileContentType, string exceptionType, string exceptionMessage, string exceptionInformation)
        {
            if (IsEnabled())
            {
                WriteEvent(103, matrixFileName, matrixFileContentBytes, matrixFileContentType, exceptionType, exceptionMessage, exceptionInformation);
            }
        }

        [Event(104, Task = Tasks.LoadWeightMatrixForProcessing, Level = EventLevel.Informational, Message = "LoadWeightMatrixForProcessing/Succeeded")]
        public void LoadWeightMatrixForProcessingSucceeded(string matrixFileName, int matrixFileContentBytes, string matrixFileContentType, string errorsLog)
        {
            if (IsEnabled())
            {
                WriteEvent(104, matrixFileName, matrixFileContentBytes, matrixFileContentType, errorsLog);
            }
        }

        [Event(105, Task = Tasks.ProcessLoadedWeightMatrices, Opcode = EventOpcode.Start, Level = EventLevel.Informational, Message = "ProcessLoadedWeightMatrices/Start")]
        public void ProcessLoadedWeightMatricesStart()
        {
            if (IsEnabled())
            {
                WriteEvent(105);
            }
        }

        [Event(106, Task = Tasks.ProcessLoadedWeightMatrices, Opcode = EventOpcode.Stop, Level = EventLevel.Informational, Message = "ProcessLoadedWeightMatrices/Stop")]
        public void ProcessLoadedWeightMatricesStop()
        {
            if (IsEnabled())
            {
                WriteEvent(106);
            }
        }

        [Event(107, Level = EventLevel.Error, Message = "ProcessLoadedWeightMatrices/Failed")]
        public void ProcessLoadedWeightMatricesFailed(string exceptionType, string exceptionMessage, string exceptionInformation)
        {
            if (IsEnabled())
            {
                WriteEvent(107, exceptionType, exceptionMessage, exceptionInformation);
            }
        }

        [Event(108, Task = Tasks.ProcessLoadedWeightMatrices, Level = EventLevel.Informational, Message = "ProcessLoadedWeightMatrices/Succeeded")]
        public void ProcessLoadedWeightMatricesSucceeded(string processedWeightMatrices)
        {
            if (IsEnabled())
            {
                WriteEvent(108, processedWeightMatrices);
            }
        }

        [Event(109, Task = Tasks.EnsureWeightsConsistencyOnCompanies, Opcode = EventOpcode.Start, Level = EventLevel.Informational, Message = "EnsureWeightsConsistencyOnCompanies/Start")]
        public void EnsureWeightsConsistencyOnCompaniesStart()
        {
            if (IsEnabled())
            {
                WriteEvent(109);
            }
        }

        [Event(110, Task = Tasks.EnsureWeightsConsistencyOnCompanies, Opcode = EventOpcode.Stop, Level = EventLevel.Informational, Message = "EnsureWeightsConsistencyOnCompanies/Stop")]
        public void EnsureWeightsConsistencyOnCompaniesStop()
        {
            if (IsEnabled())
            {
                WriteEvent(110);
            }
        }

        [Event(111, Level = EventLevel.Error, Message = "EnsureWeightsConsistencyOnCompanies/Failed")]
        public void EnsureWeightsConsistencyOnCompaniesFailed(string exceptionType, string exceptionMessage, string exceptionInformation)
        {
            if (IsEnabled())
            {
                WriteEvent(111, exceptionType, exceptionMessage, exceptionInformation);
            }
        }

        [Event(112, Task = Tasks.EnsureWeightsConsistencyOnCompanies, Level = EventLevel.Informational, Message = "EnsureWeightsConsistencyOnCompanies/Succeeded")]
        public void EnsureWeightsConsistencyOnCompaniesSucceeded(string processedWeightMatrixIdCompanId)
        {
            if (IsEnabled())
            {
                WriteEvent(112, processedWeightMatrixIdCompanId);
            }
        }

        public class Tasks
        {
            public const EventTask LoadWeightMatrixForProcessing = (EventTask)0x1;// > 0
            public const EventTask ProcessLoadedWeightMatrices = (EventTask)0x2;// > 0
            public const EventTask EnsureWeightsConsistencyOnCompanies = (EventTask)0x3;// > 0
        }
    }
}
